package com.ruoyi.common.utils.sms;

import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.ruoyi.common.config.SmsConfig;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;


@Component
public class SendSms {

	protected static Log log=LogFactory.getLog(SendSms.class);
	@Autowired
	private RedisCache redisServer;
	@Autowired
	@Qualifier("scf")
	private SmsConfig smsConfig;
	public static final String SMSFORMAT = "00";
	public static final String RANDCODE = "SMSService:randcode:%s";
	public static final String NUM = "SMSService:num:%s";
	public boolean isAvailable(String telephone, String randcode) {
		String key = String.format(RANDCODE, telephone);
		String _randcode = redisServer.getCacheObject(key);
		if(randcode.equals(_randcode)) {
			delAli(telephone, randcode);
			return true;
		}else
			return false;
	}
	
	public void delAli(String telephone, String randcode) {
		String key = String.format(RANDCODE, telephone);
		redisServer.deleteObject(key);
	}
	
	public String sendSms(String telephone,String areaCode,String language,String code) {
		
		String key = String.format(RANDCODE, telephone);
		String number = String.format(NUM, telephone);//次数
		Long ttl = redisServer.getExpire(number);
		code=redisServer.getCacheObject(key);
		if (ttl >540) {
			String msg="请不要频繁请求验证码";
			 msg=MessageFormat.format(msg,ttl-540);
			System.out.println("======  "+msg);
			throw new ServiceException(msg,0);
		}
		redisServer.setCacheObject(number, telephone, 540, TimeUnit.SECONDS);
	
		if(null==code)
			code=  StringUtils.randomCode();
		final String smsCode=code;
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if (1 == smsConfig.getOpenSMS()) { // 需要发送短信
					aliSMS(telephone, language, smsCode, areaCode, key);
					redisServer.setCacheObject(key, smsCode);
					redisServer.expire(key, 600);
				}
			}
		}).start();
	
		 return code;
	}
	
	// 阿里云短信服务
		public void aliSMS(String telephone, String language,String smsCode, String areaCode,String key){
			try {
				SendSmsResponse sendSms = sendSmss(telephone, smsCode, areaCode);
				if(null!=sendSms&&"OK".equals(sendSms.getCode()))
					redisServer.setCacheObject(key, smsCode);
					redisServer.expire(key, 600);
				if(!StringUtils.isEmpty(sendSms.getCode()) && !"OK".equals(sendSms.getCode()))
					throw new ServiceException( sendSms.getMessage(), Integer.valueOf(sendSms.getCode()));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	
	public  SendSmsResponse sendSmss(String telephone, String code, String areaCode) throws ClientException {
		// 可自助调整超时时间
		System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
		System.setProperty("sun.net.client.defaultReadTimeout", "10000");

		// 初始化acsClient,暂不支持region化
		IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", smsConfig.getAccesskeyid(),
				smsConfig.getAccesskeysecret());
		DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", smsConfig.getProduct(),
				smsConfig.getDomain());
		IAcsClient acsClient = new DefaultAcsClient(profile);

		// 组装请求对象-具体描述见控制台-文档部分内容
		SendSmsRequest request = new SendSmsRequest();
		// 必填:待发送手机号
		log.debug("格式化手机号 :  00 + 国际区号 + 号码   ==========>"+"   SMSFORMAT :"+ SMSFORMAT +"     code: " + code + "========= areaCode: " + areaCode);
		request.setPhoneNumbers(SMSFORMAT+areaCode + telephone);// 接收号码格式为00+国际区号+号码
		// 必填:短信签名-可在短信控制台中找到
		request.setSignName(smsConfig.getSignname());
		// 必填:短信模板-可在短信控制台中找到
		request.setTemplateCode(smsConfig.getEnglishTempletecode());
		if ("86".equals(areaCode) || "886".equals(areaCode) || "852".equals(areaCode))
			request.setTemplateCode(smsConfig.getChinaseTempletecode());

		// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的用户,您的验证码为${code}"时,此处的值为
		request.setTemplateParam("{\"code\":\"" + code + "\"}");

		// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)
		// request.setSmsUpExtendCode("90997");

		// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
		// request.setOutId("yourOutId");

		// hint 此处可能会抛出异常，注意catch
		SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
		log.debug("阿里云短信服务回执详情："+JSONObject.toJSONString(sendSmsResponse));
		if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
			log.info("短信发送成功！");
//			saveSMSToDB(request.getPhoneNumbers(), areaCode, code, request.getSignName()+request.getTemplateCode(), sendSmsResponse.getRequestId());
		} else {
			log.info("短信发送失败！");
		}
		return sendSmsResponse;
	}
	
}
